package luj.tool.jnproxyan.proxy.network.socks.actor.root.message.admin.stats;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import luj.tool.jnproxyan.proxy.admin.AdminHttpHandler;
import luj.tool.jnproxyan.proxy.admin.http.render.TimeValueRenderer;
import luj.tool.jnproxyan.proxy.network.socks.actor.root.Socks5Actor;
import luj.tool.jnproxyan.proxy.stats.connect.ConnectStats;
import luj.tool.jnproxyan.proxy.util.data.session.DataUsingStarter;
import luj.tool.jnproxyan.proxy.util.data.wrap.ResultByIdLWrapper;
import luj.tool.jnproxyan.proxy.util.data.wrap.ResultGlobalLWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

@Component
final class OnStatsConnect implements Socks5Actor.Handler<StatsConnectMsg> {

  @Override
  public void onHandle(Context ctx) throws Exception {
    Socks5Actor self = ctx.getActorState(this);
    StatsConnectMsg msg = ctx.getMessage(this);

    DataUsingStarter.Session data = _dataUser.inject(self).start();
    var stats = _globalLoader.load(data).andWrap(ConnectStats.class);

    List<?> itemList = stats.statsMap().values().stream()
        .map(id -> _byIdLoader.load(id, data).andWrap(ConnectStats.Item.class))
        .sorted(comparing((ConnectStats.Item i) -> i.lastFailTime().get()).reversed())
        .map(this::makeRow)
        .collect(Collectors.toList());

    //TODO: 平均速度 走代理能不能通
    Map<String, ?> table = ImmutableMap.of(
        "header", ImmutableList.of("地址", "总访问", "失败数", "最近失败"),
        "body", itemList
    );

    AdminHttpHandler.Context http = msg.http();
    http.responsePage(ImmutableMap.of(
        "table", http.encodeJson(table)
    ));
  }

  private Map<String, ?> makeRow(ConnectStats.Item item) {
    String host = item.host().get();
    int total = item.requestTotal().get();

    int fail = item.failCount().get();
    String lastTime = new TimeValueRenderer().render(item.lastFailTime().get());

    return ImmutableMap.of(
        "data", ImmutableList.of(host, total, fail, lastTime)
    );
  }

  @Autowired
  DataUsingStarter _dataUser;

  @Autowired
  ResultGlobalLWrapper _globalLoader;

  @Autowired
  ResultByIdLWrapper _byIdLoader;
}
